﻿using System;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;

namespace CheckFocusedWindowURL
{
    class Program
    {
        static void Main(string[] args)
        {
            // 获取当前窗口的进程ID
            int foregroundProcessId = GetForegroundProcessId();

            // 获取所有网络接口
            NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface networkInterface in networkInterfaces)
            {
                IPInterfaceProperties ipProperties = networkInterface.GetIPProperties();
                if (ipProperties != null)
                {
                    // 获取IPv4全局属性
                    IPGlobalProperties globalProperties = IPGlobalProperties.GetIPGlobalProperties();
                    TcpConnectionInformation[] connections = globalProperties.GetActiveTcpConnections();

                    foreach (TcpConnectionInformation connection in connections)
                    {
                        // 获取连接的本地端口和远程端口
                        IPEndPoint localEndPoint = connection.LocalEndPoint;
                        IPEndPoint remoteEndPoint = connection.RemoteEndPoint;

                        // 获取与当前窗口关联的连接的进程ID
                        int processId = GetConnectionProcessId(connection);

                        if (processId == foregroundProcessId)
                        {
                            // 输出与当前窗口关联的网络连接的本地IP地址和端口
                            Console.WriteLine($"当前窗口关联的网络连接本地地址：{localEndPoint.Address}:{localEndPoint.Port}");
                            break;
                        }
                    }
                }
            }
        }

        // 获取当前窗口的进程ID
        static int GetForegroundProcessId()
        {
            IntPtr foregroundWindow = GetForegroundWindow();
            GetWindowThreadProcessId(foregroundWindow, out int processId);
            return processId;
        }

        // 获取与连接关联的进程ID
        static int GetConnectionProcessId(TcpConnectionInformation connection)
        {
            int processId = 0;
            GetExtendedTcpTable(IntPtr.Zero, out int tableSize, true, AddressFamily.InterNetwork, TcpTableClass.OwnerPidAll, 0);
            IntPtr tcpTablePtr = Marshal.AllocHGlobal(tableSize);

            try
            {
                int result = GetExtendedTcpTable(tcpTablePtr, out tableSize, true, AddressFamily.InterNetwork, TcpTableClass.OwnerPidAll, 0);
                if (result == 0)
                {
                    MibTcpRowOwnerPid[] tcpTableRows = new MibTcpRowOwnerPid[tableSize / Marshal.SizeOf(typeof(MibTcpRowOwnerPid))];
                    int rowSize = Marshal.SizeOf(typeof(MibTcpRowOwnerPid));
                    IntPtr currentRowPtr = tcpTablePtr;

                    for (int i = 0; i < tcpTableRows.Length; i++)
                    {
                        tcpTableRows[i] = (MibTcpRowOwnerPid)Marshal.PtrToStructure(currentRowPtr, typeof(MibTcpRowOwnerPid));
                        currentRowPtr = IntPtr.Add(currentRowPtr, rowSize);

                        // 寻找匹配的连接信息
                        if (tcpTableRows[i].LocalEndPoint.Equals(connection.LocalEndPoint) && tcpTableRows[i].RemoteEndPoint.Equals(connection.RemoteEndPoint))
                        {
                            processId = tcpTableRows[i].OwningPid;
                            break;
                        }
                    }
                }
            }
            finally
            {
                Marshal.FreeHGlobal(tcpTablePtr);
            }

            return processId;
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();

        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId);

        [System.Runtime.InteropServices.DllImport("iphlpapi.dll", SetLastError = true)]
        public static extern int GetExtendedTcpTable(IntPtr pTcpTable, out int pdwSize, bool bOrder, System.Net.Sockets.AddressFamily ulAf, TcpTableClass TableClass, int Reserved);

        public enum TcpTableClass
        {
            BasicListener,
            BasicConnections,
            BasicAll,
            OwnerPidListener,
            OwnerPidConnections,
            OwnerPidAll,
            OwnerModuleListener,
            OwnerModuleConnections,
            OwnerModuleAll
        }

        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct MibTcpRowOwnerPid
        {
            public uint State;
            public uint LocalAddr;
            [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] LocalPort;
            public uint RemoteAddr;
            [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] RemotePort;
            public uint OwningPid;
        }
    }
}
